<?php
/**
 * File: hackystatUpload.php
 * 
 * This PHP script is used to retrieve and parse user data from the Hackystat server
 * and store it into iHacky database.  This script takes a long time to run depending
 * on the amount Hackystat data from the users.  The script has two phases, one is to
 * serve users that are new to the iHacky database and the other is for users that 
 * already have data in the iHacky database.  The reason for this is to minimize overhead.
 * 
 * The script's algorithm works as follow:
 * -Retrieve iHacky user's Hackystat login info, if they exist.
 * -Check if the user is new to iHacky or not.
 * ---If new, then grab data from past 50 days. (set by dayCounter)
 * ---If old, then grab data for past 1 day.
 * -Invoke Hackystat server URIs to retrieve DevEvent data for the user.
 * -Store the filename attribute of the URI result into a map. (used to determine related class)
 * ---Count the number of times the filename repeated (used to calculate rank) 
 * -Invoke Hackystat server URIs to retrieve Coupling data for the user.
 * -Store the filename and class info from the URI result into a map.
 * -Compare the two maps to see if there is a match in filenames.
 * ---If yes, then grab the repeat count and use that number to calculate rank.
 * ------Store that rank into that user's class data.
 * ---------If that class is new then add to the Class table in the database
 *           and reference that user with it.
 * ---------If the class exist then replace the Rank calculated with the current rank 
 *           in the database.
 * ---If no, then neglect the data because there is no Coupling data for that filename.
 * -First used and Last used time from the Coupling data is also stored into the database
 *   for the user.
 * -Repeat the process for the next user in the database.
 * Ends algorithm 
 *
 * This script is planned to be invoked once per day on the same time. Use the web server's
 * CRON Job feature to invoke this script.
 * If the script successfully completes it will print out "Success".
 *
 * Formula for the Rank: 
 * -DevEvent occurence -Rank
 *       1 to 10          1
 *       50 to 100        2
 *       100 to 150       3
 *       150 to 200       4
 *       200 and above    5
 *
 *
 *
 */ 
 /**
  * 
  */
 
//include 'mockajaxfbconfig.php';
include 'iHackyFunctions.php';
include 'lib/config.php';
include 'getXMLData.php';



$conn = getDbConn();

//query to retrieve users hackystat login info
$qryGetAllUsers = "SELECT facebook_id, hackystat_id, AES_DECRYPT(hackystat_password, '414') AS 'hackystat_password',
                          status FROM USERS";
$resultGetAllUsers = mysql_query($qryGetAllUsers, $conn) or DIE(mysql_error()."Error: qryGetAllUsers");

//echo $resultGetAllUsers . "step 0<br>";

//while loop to iterate through each user in the ihacky database
while($userInfoArray = mysql_fetch_array($resultGetAllUsers)){

	//echo "going thru each user: step 1<br>";
	//create all the necessary arrays to store all the data being gathered for each user
	$dependencyArray = array();
	$hrefCouplingArray = array();
	$hrefDevEventArray = array();
	$dependencyStartTimeMap = array();
	$dependencyLastTimeMap = array();
	$devEventFilenameMap = array();
	$dependencyRankMap = array();

	//echo "going thru each user: step 1.5<br>";
	$endTime = 0;
	$startDate = 0;
	$dayCounter = 50;
	$rank = 0;

	while($endTime != date(DATE_ATOM, mktime(0,0,0,date("m"), date("d")+1, date("Y")))){
		// new == new iHacky user;  old == previous iHacky user
		if($userInfoArray['status'] == "old"){


			$startTime  = date(DATE_ATOM, mktime(0,0,0,date("m"), date("d")-1, date("Y")));
			$endTime = date(DATE_ATOM, mktime(0,0,0,date("m"), date("d")+1, date("Y")));
			echo "Start Time: ".$startTime."<br>";
			echo "End Time: ".$endTime."<br>";
		}
		else if($userInfoArray['status'] == "new"){

			$startTime = date(DATE_ATOM, mktime(0,0,0,date("m"), date("d")-$dayCounter, date("Y")));
			$endTime = date(DATE_ATOM, mktime(0,0,0,date("m"), date("d")-($dayCounter-1), date("Y")));
			$dayCounter--;
		}
			
			
		//hackystat Sensordata URI which grabs sensordata between 2 unix time stamps
		$hackystatSensorDataURI = "http://dasha.ics.hawaii.edu:9876/sensorbase/".
	                        "sensordata/".$userInfoArray['hackystat_id']."?lastModStartTime=$startTime&lastModEndTime=$endTime";
			

		//echo "Before Dasha<br>";
			
		//retrieves xml data from the hackystat server REST API and places it in a multi-dimensional array
		$sensorDataUserArray = retrieveXML($hackystatSensorDataURI, $userInfoArray['hackystat_id'], $userInfoArray['hackystat_password']);
			
		//echo "After Dasha<br>";
		//loop through each entry to store HREF value from DevEvent data
		if($sensorDataUserArray[0]['children'] != null){
			for($i = 0; $i < sizeof($sensorDataUserArray[0]['children']); $i++){
				//echo "going thru each devEvent step 2<br>";
			  if($sensorDataUserArray[0]['children'][$i]['attributes']['SENSORDATATYPE'] == "DevEvent"){
			    if(isset($sensorDataUserArray[0]['children'][$i]['attributes']['HREF'])) {
		  		  $hrefDevEventArray[] = $sensorDataUserArray[0]['children'][$i]['attributes']['HREF'];
			    }
			    //echo 'HREF DEVEVENT INFO: ' . $sensorDataUserArray[0]['children'][$i]['attributes']['HREF'] . '<br>';
			  }
			  if($sensorDataUserArray[0]['children'][$i]['attributes']['SENSORDATATYPE'] == "Coupling"){
				 //echo "<br>Before if HREF Coupling info<br>";
			    if(isset($sensorDataUserArray[0]['children'][$i]['attributes']['HREF'])) {
			  	  echo "<br>Prints if isset HREF<br>";
		  		  $hrefCouplingArray[] = $sensorDataUserArray[0]['children'][$i]['attributes']['HREF'];
			    }
			    //echo 'HREF COUPLING INFO: ' . $sensorDataUserArray[0]['children'][$i]['attributes']['HREF'] . '<br>';
			  }
			}//end of for loop
		}//end of first if statment
			
		//iterate through each HREF value from the DevEvent data and gather the XML data and store into 
		//multidimensional array.
		foreach($hrefDevEventArray as $link){
			
			//retrieve XML data from each HREF link and store into multi-dimensional array
			$devEventInfoArray = retrieveXML($link, $userInfoArray['hackystat_id'], $userInfoArray['hackystat_password']);

			$devEventFilename = $devEventInfoArray[0]['children'][4]['tagData'];
			//echo "<br>+++y++++" . $devEventFilename;
			
			//parse the value of the file name to retrieve the class name only
			$parsedDevEventFilename = parseDevEventFilename($devEventFilename);

			if(array_key_exists($parsedDevEventFilename, $devEventFilenameMap)) {
	 		  $devEventFilenameMap[$parsedDevEventFilename]++;
	 		  //echo "<br>+++++++" . $devEventFilenameMap[$parsedDevEventFilename];
			}
	 	    else {
	 		  $devEventFilenameMap[$parsedDevEventFilename] = 1;
	 		  //echo "<br>++x++++" . $devEventFilenameMap[$parsedDevEventFilename];
	 	    }
		}
			
		//echo "<br>hrefCouplingArray foreach loop<br>";
		//echo "Size of hrefCouplingArray".sizeof($hrefCouplingArray);
		
		//iterate through each HREF link from the Coupling data and store the filename and classname in a multi-dimensional array
		foreach ($hrefCouplingArray as $link){
			
			//echo "<br>going thru each HREF: step 3<br>";
			//retrieve the necessary information and store it into a multidimensional array
			$dependencyInfo = retrieveXML($link, $userInfoArray['hackystat_id'], $userInfoArray['hackystat_password']);

			//add each dependency class name to the array
			$dependencyArray[] = $dependencyInfo[0]['children'][6]['children'][3]['children'][1]['tagData'];

			//store the classname into a variable
			$dependencyItem = $dependencyInfo[0]['children'][6]['children'][3]['children'][1]['tagData'];


			//store the Coupling sensor data file name into a variable
			$dependencyFilename = $dependencyInfo[0]['children'][4]['tagData'];
			//echo "<br>++zz++" . $dependencyFilename;

			//parse the Dependency file name to only get the actual class name
			$parsedDependencyFilename = parseDependencyFilename($dependencyFilename);
			//echo "<br>++gg++" . $parsedDependencyFilename;

			//rank: 1:10 2:50 3:100 4:200 5:200+
			//test the int value in the MAP to see which rank is assigned and store the number in $rank
			if(array_key_exists($parsedDependencyFilename, $devEventFilenameMap)){
					
				if($devEventFilenameMap[$parsedDependencyFilename] >= 1) {
					//rank 1
					$rank = 1;
				}
				if($devEventFilenameMap[$parsedDependencyFilename] >= 50) {
					//rank 2
					$rank = 2;
				}
				if($devEventFilenameMap[$parsedDependencyFilename] >= 100) {
					//rank 3
					$rank = 3;
				}
				if($devEventFilenameMap[$parsedDependencyFilename] >= 150) {
					//rank 4
					$rank = 4;
				}
				if($devEventFilenameMap[$parsedDependencyFilename] >= 200) {
					//rank 5
					$rank = 5;
				}
			}
            
			//store the rank number in the dependency rank map
			$dependencyRankMap[$dependencyItem] = $rank;

			//store the current time stamp of the sensordata we are iterating through
			$timeStamp = $dependencyInfo[0]['children'][0]['tagData'];

			//check to see if the Key value exist for the timestamp.  If exist,
			//check the timestamp to determine the min and max value of the timestamp.
			//If time stamp does not exist, create one and store the current timestamp.
			if(array_key_exists($dependencyItem, $dependencyStartTimeMap)){

				//if dependency time stamp is greater than currently stored timestamp, store new timestamp
				if($dependencyStartTimeMap[$dependencyItem] > $timeStamp){
			      $dependencyStartTimeMap[$dependencyItem] = $timeStamp;
				}
			}
			else{
				//if dependency name key does not exist, create one and store current timestamp
				$dependencyStartTimeMap[$dependencyItem] = $timeStamp;
			}

			//test to see if time stamp is less than the currently stored timestamp in map.
			if(array_key_exists($dependencyItem, $dependencyLastTimeMap)){

				//test to see if currently stored timestamp in map is less then currently read timestamp
				if($dependencyLastTimeMap[$dependencyItem] < $timeStamp){
			      $dependencyLastTimeMap[$dependencyItem] = $timeStamp;
				}
			}
			else{
				//if map key does not exist of dependency name, create one and store current timestamp
				$dependencyLastTimeMap[$dependencyItem] = $timeStamp;
			}

		} //foreach
			
		//PHP built in function to remove any redundant dependency names in the array
		$dependencyArray = array_unique($dependencyArray);
			
		//iterate through each dependency name in the array and insert or update it to the database
		foreach ($dependencyArray as $dependency){
			
			//query to check if dependency name already exist in database
			$qrySelectDependency = "SELECT * FROM CLASS WHERE class_detail = '$dependency';";
			$resultFromExistDependency = mysql_query($qrySelectDependency, $conn) or DIE(mysql_error()."Conn 2");
			$result = mysql_fetch_array($resultFromExistDependency);

			//echo $result[0] . " the result if dependency exist: step 4 <br>";
			//if query returns no results, then we add the new dependency name into the database
			if(!$result){

				$parsedDependencyStringArray = explode(".", $dependency);
				$dependencyClassName = end($parsedDependencyStringArray);

				echo "Class Name: ".$dependencyClassName."<br>";

				//query to insert new dependency name into the database
				$qryInsertDependency = "INSERT IGNORE INTO CLASS (class_name, class_detail) VALUES ('$dependencyClassName','$dependency');";
				$result1 = mysql_query($qryInsertDependency, $conn) or DIE(mysql_error()."Error: qryInsertDependency");
				echo $result1 . "if not result: step 5<br>";

			}

			//query to select the ID class number 
			$qryGetClassID = "SELECT class_id FROM CLASS WHERE class_detail = '$dependency'";
			$resultClassID = mysql_query($qryGetClassID, $conn) or DIE(mysql_error()."Error: qryGetClassID");
			$classIDArray = mysql_fetch_array($resultClassID);

			$classID = $classIDArray['class_id'];
			$facebookID = $userInfoArray['facebook_id'];
			$startDateArray = date_parse($dependencyStartTimeMap[$dependency]);
			$startDate = $startDateArray['year']."-".$startDateArray['month']."-".$startDateArray['day'];

			$lastDateArray = date_parse($dependencyLastTimeMap[$dependency]);
			$lastDate = $lastDateArray['year']."-".$lastDateArray['month']."-".$lastDateArray['day'];

			$usedDate = 0;

			//echo "Rank before testing: ".$rank;
			//echo "<br>DependencyName: ".$dependency;
			
			//check to see of there exist a dependency class name in the map and if exist
			//retrieve the value of the key which is the rank number. Else, set default rank
			// to 1
			if(array_key_exists($dependency, $dependencyRankMap)){
				$rank = $dependencyRankMap[$dependency];
				echo '<br>Rank: '.$rank;
			}
			else{
				$rank = 1;
			}

			//call function to insert entry into intersection table with all the necessary data
			echo db_insertClass_Users($conn, $facebookID, $classID, $startDate, $lastDate, $usedDate, $rank)." Step 6 <br>";


		}//end of foreach loop dependency
			

	}//end of while loop for date

	//update the users status to old
	$facebookID = $userInfoArray['facebook_id'];
	$qryUpdateUserStatus = "UPDATE USERS SET status='old' WHERE facebook_id = $facebookID";
	mysql_query($qryUpdateUserStatus, $conn) or DIE(mysql_error());

}//end of users while loop

echo db_updateCron_Jobs($conn, 'Classes') . "Step 7<br>";
echo db_updateCron_Jobs($conn, 'Test');

closeDb($conn);
echo 'Success';

/**
 * 
 *
 * @param unknown_type $conn
 * @param unknown_type $facebookID
 * @param unknown_type $classID
 * @param unknown_type $startDate
 * @param unknown_type $lastDate
 * @param unknown_type $usedDate
 * @param unknown_type $rank
 * @return unknown
 */
function db_insertClass_Users($conn, $facebookID, $classID, $startDate, $lastDate, $usedDate, $rank) {

	$query = "INSERT IGNORE INTO CLASS_USERS (facebook_id, class_id, time_start, time_last, time_used, class_rank)
	VALUES ('$facebookID', '$classID', '$startDate', '$lastDate', '$usedDate', '$rank')
	ON DUPLICATE KEY UPDATE
	CLASS_USERS.time_start =
	IF ( '$startDate' < CLASS_USERS.time_start,
	'$startDate', CLASS_USERS.time_start
	),
	CLASS_USERS.time_last =
	IF ( '$lastDate' > CLASS_USERS.time_last,
	'$lastDate', CLASS_USERS.time_last
	),
	CLASS_USERS.time_used =
	IF ( '$usedDate' = 0,
	DATEDIFF(CLASS_USERS.time_last, CLASS_USERS.time_start), '$usedDate'
	),
	CLASS_USERS.class_rank =
	IF ( '$rank' > 0,
	'$rank', CLASS_USERS.class_rank
	);";

	$result = mysql_query($query, $conn) or DIE(mysql_error()." db_insertClass_Users()");

	return $result;
}

/**
 * Enter description here...
 *
 * @param unknown_type $conn
 * @param unknown_type $cronjobName
 * @return unknown
 */
function db_updateCron_Jobs($conn, $cronjobName) {
	$query = "INSERT IGNORE INTO CRON_JOBS (cronjob_name, timestamp)
	VALUES ('$cronjobName', NOW())
	ON DUPLICATE KEY UPDATE
	CRON_JOBS.timestamp = NOW();";

	$result = mysql_query($query, $conn) or DIE(mysql_error()." db_updateCron_Jobs");
	return $result;
}

/**
 * Enter description here...
 *
 * @param unknown_type $string
 * @return unknown
 */
function parseDependencyFilename($string){
	$parsedString = explode("\\",$string);
	return end($parsedString);
}

/**
 * Enter description here...
 *
 * @param unknown_type $string
 * @return unknown
 */
function parseDevEventFilename($string){
	$parsedString = explode("/",$string);
	return end($parsedString);
}
?>